package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.mapper.*;
import com.atguigu.tingshu.album.service.BaseCategoryService;
import com.atguigu.tingshu.common.cache.GuiGuCache;
import com.atguigu.tingshu.model.album.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@SuppressWarnings({"all"})
public class BaseCategoryServiceImpl extends ServiceImpl<BaseCategory1Mapper, BaseCategory1> implements BaseCategoryService {

    @Autowired
    private BaseCategory1Mapper baseCategory1Mapper;

    @Autowired
    private BaseCategory2Mapper baseCategory2Mapper;

    @Autowired
    private BaseCategory3Mapper baseCategory3Mapper;

    @Autowired
    private BaseCategoryViewMapper baseCategoryViewMapper;


    /**
     * 查询所有1,2,3级分类列表
     *
     * @return @return [{categoryId:1,categoryName:音乐,categoryChild:[{categoryId:1006,categoryName:音乐音效,categoryChild:[{}]},{}]},{},{}]
     */
    @Override
    @GuiGuCache(prefix = "album:category:all")
    public List<JSONObject> getBaseCategoryList() {
        //1.查询分类视图所有记录 共计401条
        List<BaseCategoryView> allCategoryViewList = baseCategoryViewMapper.selectList(null);
        //2.声明集合保存所有"1级"分类列表
        List<JSONObject> jsonObjectList1 = new ArrayList<>();

        //3.处理1级分类
        //3.1 对所有分类视图记录按照1级分类ID进行分组 得到"1级"分类Map
        Map<Long, List<BaseCategoryView>> map1 = allCategoryViewList
                .stream()
                .collect(Collectors.groupingBy(BaseCategoryView::getCategory1Id));
        //3.2 遍历"1级"分类Map
        for (Map.Entry<Long, List<BaseCategoryView>> entry1 : map1.entrySet()) {
            //3.3 创建1级分类JSONObject对象
            JSONObject jsonObject1 = new JSONObject();
            //3.3.1 获取封装1级分类ID
            Long category1Id = entry1.getKey();
            //3.3.2 获取封装1级分类名称
            String category1Name = entry1.getValue().get(0).getCategory1Name();
            jsonObject1.put("categoryId", category1Id);
            jsonObject1.put("categoryName", category1Name);
            // 4.处理2级分类
            //4.1 创建2级分类JSONObject对象集合
            List<JSONObject> jsonObject2List = new ArrayList<>();
            //4.2 对"1级"分类列表按照2级分类ID进行分组 获取"2级"分类Map
            Map<Long, List<BaseCategoryView>> map2 = entry1.getValue()
                    .stream()
                    .collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
            //4.3 遍历"2级"分类Map
            for (Map.Entry<Long, List<BaseCategoryView>> entry2 : map2.entrySet()) {
                //4.4 创建2级分类JSONObject对象
                JSONObject jsonObject2 = new JSONObject();
                //4.4.1 封装2级分类ID
                Long category2Id = entry2.getKey();
                //4.4.2 封装2级分类名称
                String category2Name = entry2.getValue().get(0).getCategory2Name();
                jsonObject2.put("categoryId", category2Id);
                jsonObject2.put("categoryName", category2Name);
                // 5.处理3级分类
                //5.1 创建3级分类JSONObject对象集合
                List<JSONObject> jsonObject3List = new ArrayList<>();
                //5.2 遍历"2级"分类视图列表
                for (BaseCategoryView baseCategoryView : entry2.getValue()) {
                    //5.3 创建3级分类JSONObject对象
                    JSONObject jsonObject3 = new JSONObject();
                    //5.3.1 封装3级分类ID
                    jsonObject3.put("categoryId", baseCategoryView.getCategory3Id());
                    //5.3.2 封装3级分类名称
                    jsonObject3.put("categoryName", baseCategoryView.getCategory3Name());
                    //5.4 将3级分类对象加入到3级分类集合中
                    jsonObject3List.add(jsonObject3);
                }
                //5.5 将3级分类集合加入到2级分类对象"categoryChild"属性中
                jsonObject2.put("categoryChild", jsonObject3List);

                //4.5 将2级分类JSONObject对象添加到"2级"分类JSONObject对象集合
                jsonObject2List.add(jsonObject2);
            }
            //4.6 将2级分类集合加入到1级分类对象"categoryChild"属性中
            jsonObject1.put("categoryChild", jsonObject2List);
            //3.4 将1级分类JSONObject对象添加到"1级"分类列表
            jsonObjectList1.add(jsonObject1);
        }
        return jsonObjectList1;
    }

    @Autowired
    private BaseAttributeMapper baseAttributeMapper;

    /**
     * 根据1级分类ID查询标签列表（包含标签值）
     *
     * @param category1Id 1级分类ID
     * @return 标签列表
     */
    @Override
    @GuiGuCache(prefix = "album:category:attribute:")
    public List<BaseAttribute> findAttribute(Long category1Id) {
        //TODO 方式1，采用MP提供QueryWrapper查询该分类下标签列表，遍历标签列表，根据标签ID查询标签值列表 需要多条SQL得到结果
        //方式2：采用动态SQL进行1对多查询，采用自定义结果集封装数据
        return baseAttributeMapper.findAttribute(category1Id);
    }

    /**
     * 根据三级分类ID查询分类视图
     *
     * @param category3Id
     * @return
     */
    @Override
    @GuiGuCache(prefix="album:categoryview:",ttl=3600, timeUnit= TimeUnit.SECONDS)
    public BaseCategoryView getCategoryView(Long category3Id) {
        return baseCategoryViewMapper.selectById(category3Id);
    }

    /**
     * 获取1级分类ID查询置顶7个三级分类列表
     *
     * @param category1Id
     * @return
     */
    @Override
    @GuiGuCache(prefix = "album:category:top3:")
    public List<BaseCategory3> findTopBaseCategory3(Long category1Id) {
        //1.根据入参1级分类ID查询二级分类列表，获取二级分类ID列表
        List<BaseCategory2> baseCategory2List = baseCategory2Mapper.selectList(
                new LambdaQueryWrapper<BaseCategory2>()
                        .eq(BaseCategory2::getCategory1Id, category1Id)
                        .select(BaseCategory2::getId)
        );

        //2.根据二级分类ID列表查询置顶7个三级3级分类列表
        if (CollUtil.isNotEmpty(baseCategory2List)) {
            List<Long> category2IdList = baseCategory2List.stream().map(BaseCategory2::getId)
                    .collect(Collectors.toList());

            List<BaseCategory3> baseCategory3List = baseCategory3Mapper.selectList(
                    new LambdaQueryWrapper<BaseCategory3>()
                            .eq(BaseCategory3::getIsTop, 1)
                            .in(BaseCategory3::getCategory2Id, category2IdList)
                            .orderByAsc(BaseCategory3::getOrderNum)
                            .last("limit 7")
            );
            return baseCategory3List;
        }
        return null;
    }

    /**
     * 查询某个1级分类（包含二三级分类列表）
     *
     * @param category1Id
     * @return
     */
    @Override
    @GuiGuCache(prefix = "album:category:list")
    public JSONObject getBaseCategoryListByCategroy1Id(Long category1Id) {
        //1.处理1级分类
        //1.1 根据1级分类ID查询分类视图，得到"1级"分类列表，获取列表第一条记录即可
        List<BaseCategoryView> baseCategory1List = baseCategoryViewMapper.selectList(
                new LambdaQueryWrapper<BaseCategoryView>()
                        .eq(BaseCategoryView::getCategory1Id, category1Id)
        );
        //1.2 创建1级分类JSON对象
        JSONObject jsonObject1 = new JSONObject();
        //1.2.1 封装1级分类对象中分类ID
        jsonObject1.put("categoryId", baseCategory1List.get(0).getCategory1Id());
        //1.2.2 封装1级分类对象中分类名称
        jsonObject1.put("categoryName", baseCategory1List.get(0).getCategory1Name());

        //2.处理2级分类
        //2.1 创建2级分类JSON对象集合
        List<JSONObject> jsonObject2List = new ArrayList<>();
        //2.2 对"1级分类"列表按照2级分类ID进行分组，得到"2级分类"Map
        Map<Long, List<BaseCategoryView>> map2 = baseCategory1List.stream()
                .collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
        //2.2 遍历"2级分类"Map
        for (Map.Entry<Long, List<BaseCategoryView>> entry2 : map2.entrySet()) {
            //2.3 创建2级分类JSON对象
            JSONObject jsonObject2 = new JSONObject();
            //2.3.1 封装2级分类JSON对象分类ID
            jsonObject2.put("categoryId", entry2.getKey());
            //2.3.2 封装2级分类JSON对象分类名称
            jsonObject2.put("categoryName", entry2.getValue().get(0).getCategory2Name());
            //2.4 将2级分类对象加入到2级分类集合中
            jsonObject2List.add(jsonObject2);
            //3.处理3级分类
            //3.1 创建3级分类集合
            List<JSONObject> jsonObject3List = new ArrayList<>();
            //3.2 遍历"2级分类"列表
            for (BaseCategoryView baseCategoryView : entry2.getValue()) {
                //3.3 创建3级分类JSON对象
                JSONObject jsonObject3 = new JSONObject();
                //3.3.1 封装3级分类ID
                jsonObject3.put("categoryId", baseCategoryView.getCategory3Id());
                //3.3.2 封装3级分类名称
                jsonObject3.put("categoryName", baseCategoryView.getCategory3Name());
                //3.4 将3级分类对象加入到3级分类集合中
                jsonObject3List.add(jsonObject3);
            }

            //3.5 将3级分类集合加入2级分类对象"categoryChild"属性中
            jsonObject2.put("categoryChild", jsonObject3List);
        }
        //2.5 将2级分类集合加入到1级分类对象中"categoryChild"属性中
        jsonObject1.put("categoryChild", jsonObject2List);

        //4.响应1级分类对象
        return jsonObject1;
    }
}
